package utils

import (
	"database/sql"
	"database/sql/driver"
	"time"
)

const (
	DateFormat = `"2006-01-02"`
	TimeFormat = `"2006-01-02 15:04:05"`
)

// Date 相关
type Date time.Time

func (d Date) String() string {
	return time.Time(d).Format(DateFormat)
}

func (d Date) MarshalJSON() ([]byte, error) {
	return []byte(d.String()), nil
}

func (d *Date) UnmarshalJSON(b []byte) error {
	date, err := time.ParseInLocation(DateFormat, string(b), time.Local)
	if err != nil {
		return err
	}
	*d = Date(date)
	return nil
}

func (d *Date) Scan(value interface{}) (err error) {
	nullTime := &sql.NullTime{}
	err = nullTime.Scan(value)
	*d = Date(nullTime.Time)
	return
}

func (d Date) Value() (driver.Value, error) {
	y, m, dd := time.Time(d).Date()
	return time.Date(y, m, dd, 0, 0, 0, 0, time.Local), nil
}

func (d Date) GormDataType() string {
	return "date"
}

// Datetime 相关
type Datetime time.Time

func (d Datetime) String() string {
	return time.Time(d).Format(TimeFormat)
}

func (d Datetime) MarshalJSON() ([]byte, error) {
	return []byte(d.String()), nil
}

func (d *Datetime) UnmarshalJSON(b []byte) error {
	datetime, err := time.Parse(TimeFormat, string(b))
	if err != nil {
		return err
	}
	*d = Datetime(datetime)
	return nil
}

func (d *Datetime) Scan(value interface{}) (err error) {
	nullTime := &sql.NullTime{}
	err = nullTime.Scan(value)
	*d = Datetime(nullTime.Time)
	return
}

func (d Datetime) Value() (driver.Value, error) {
	datetime := time.Time(d)
	year, month, day := datetime.Date()
	hour, min, sec := datetime.Clock()
	return time.Date(year, month, day, hour, min, sec, 0, time.Local), nil
}

func (d Datetime) GormDataType() string {
	return "datetime"
}
